In [7]:
from IPython.display import clear_output
import factors
import inspect
n = 0
regression=False; N = 0 # run particular factor/ regression
for name, obj in inspect.getmembers(factors, predicate=inspect.isclass):
    if obj.__module__ == "factors":
        if n==N or regression==True:
            clear_output(wait=False)
            %run -i backtest.py {name}
            factor_name = name  
        n = n+1
factor analysis begin:  Factor0_Random 2024-02-23 02:24:00.305823
analysis factor/portfolio:  True/True
long-short/group neutral:  True/False
strategy:  eq_weight optimize:  max_sharpe
simulation_time:                 0
start 2014-01-01
end   2017-01-01
use_storage_data:  True
Dropped 18.1% entries from factor data: 18.1% in forward returns computation and 0.0% in binning phase (set max_loss=0 to see potentially suppressed Exceptions).
max_loss is 50.0%, not exceeded: OK!
        factors:  (756000, 2)
         prices:  (756, 1655)
     pf_returns:  (1086,)
   pf_positions:  (1086, 507)
pf_transactions:  (2199, 8)
   pf_benchmark:  (1080,)
Quantiles Statistics
min max mean std count count %
factor_quantile
1 1.0 635.0 269.319560 173.653639 124149 20.047799
2 528.0 1234.0 856.992474 170.550635 123708 19.976585
3 1054.0 1860.0 1459.461475 177.464277 123699 19.975132
4 1577.0 2523.0 2044.316366 203.111005 123708 19.976585
5 2145.0 3139.0 2673.117531 214.071579 124001 20.023899
Returns Analysis
1D 5D 10D
Ann. alpha -0.008 -0.016 -0.017
beta 0.026 0.016 0.014
Mean Period Wise Return Top Quantile (bps) -0.098 -0.222 -0.243
Mean Period Wise Return Bottom Quantile (bps) 0.639 1.456 1.603
Mean Period Wise Spread (bps) -0.737 -1.654 -1.817
<Figure size 432x288 with 0 Axes>
Information Analysis
1D 5D 10D
IC Mean -0.002 -0.004 -0.005
IC Std. 0.037 0.038 0.039
Risk-Adjusted IC -0.046 -0.111 -0.115
t-stat(IC) -1.268 -3.038 -3.148
p-value(IC) 0.205 0.002 0.002
IC Skew 0.000 0.113 0.004
IC Kurtosis -0.326 -0.058 -0.511
Turnover Analysis
10D 1D 5D
Quantile 1 Mean Turnover 0.030 0.007 0.017
Quantile 2 Mean Turnover 0.038 0.009 0.023
Quantile 3 Mean Turnover 0.040 0.010 0.024
Quantile 4 Mean Turnover 0.043 0.010 0.025
Quantile 5 Mean Turnover 0.032 0.007 0.018
1D 5D 10D
Mean Factor Rank Autocorrelation 1.0 1.0 1.0
<Figure size 432x288 with 0 Axes>
Entire data start date: 2014-01-03
Entire data end date: 2016-12-22
Backtest months: 51
Backtest
Annual return -1.5%
Cumulative returns -6.2%
Annual volatility 0.9%
Sharpe ratio -1.72
Calmar ratio -0.21
Stability 0.84
Max drawdown -7.2%
Omega ratio 0.63
Sortino ratio -1.93
Skew -5.46
Kurtosis 61.24
Tail ratio 0.75
Daily value at risk -0.1%
Gross leverage 0.71
Daily turnover 0.3%
Alpha -0.01
Beta 0.00
Worst drawdown periods Net drawdown in % Peak date Valley date Recovery date Duration
0 7.18 2014-10-16 2016-02-24 NaT NaN
1 1.07 2014-02-02 2014-05-22 2014-09-11 159
2 0.19 2014-01-05 2014-01-13 2014-01-17 10
3 0.08 2014-09-17 2014-09-29 2014-10-06 14
4 0.00 2014-01-28 2014-01-29 2014-01-30 3
Stress Events mean min max
Apr14 -0.00% -0.05% 0.05%
Oct14 -0.02% -0.11% 0.03%
Fall2015 -0.05% -0.72% 0.02%
New Normal -0.01% -0.72% 0.16%
In-sample months: 47
Out-of-sample months: 3
All In-sample Out-of-sample
Annual return -1.5% -1.4% -2.5%
Cumulative returns -6.2% -5.5% -0.7%
Annual volatility 0.9% 0.9% 0.5%
Sharpe ratio -1.73 -1.60 -5.41
Calmar ratio -0.21 -0.20 -3.02
Stability 0.84 0.83 0.75
Max drawdown -7.2% -7.2% -0.8%
Omega ratio 0.63 0.65 0.39
Sortino ratio -1.93 -1.79 -5.93
Skew -5.45 -5.42 0.01
Kurtosis 60.99 59.06 -0.42
Tail ratio 0.75 0.73 0.79
Daily value at risk -0.1% -0.1% -0.1%
Gross leverage 0.71 0.71 0.73
Daily turnover 0.3% 0.3% 0.3%
Alpha -0.01 -0.01 -0.02
Beta 0.00 0.00 -0.02
Analysis: done
In [10]:
from IPython.display import Javascript
from nbconvert import HTMLExporter

def save_notebook():
    display(
        Javascript("IPython.notebook.save_notebook()"),
        include=['application/javascript']
    )

def output_HTML(current_file, output_file):
    import codecs
    import nbformat
    exporter = HTMLExporter()
    output_notebook = nbformat.read(current_file, as_version=4)
    output, resources = exporter.from_notebook_node(output_notebook)
    file = codecs.open(output_file, 'w', encoding='utf-8')
    file.write(output)
    file.close()

print('saved: ', factor_name)
current_file = 'regression.ipynb'
output_file = f'results/factor_{factor_name}.html'
output_HTML(current_file, output_file)
saved:  Factor0_Random